/************************************************************************
* Model class, describe data content, including mapping, next items, 
* color, etc ...
* Author : Shaolan
* Version : 1.0
* Website : http://shaolan.net
*/
#ifndef MODEL_HEADER
	#include "model.hpp"
	#define MODEL_HEADER 1
#endif

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// ***********************************************************************************************************************************
// Block structure definition
Block::Block(){
	x = y = speed = start = 0;
	for (int i = 0 ; i < 4 ; i++) data[i] = EMPTY;
}

Block::Block(int i,int j,Item d[4]){
	x = i;
	y = j;
	start = speed = 0;
	for (int k = 0 ; k < 4 ; k++) data[k] = d[k];
}

// ***********************************************************************************************************************************
// Public Constructor
Model::Model(){
	mapping = NULL;
	setWidth(0);
	setHeight(0);
	setScore(0);
	fillNext();
}

Model::Model(int w,int h){
	srand(time(NULL));
	setWidth(w);
	setHeight(h);
	// Set Mapping
	mapping = new Item*[width];
	for (int i = 0 ; i < width ; i++){
		mapping[i] = new Item[height];
		for (int j = 0 ; j < height ; j++) setMapping(i,j,EMPTY); 
	}
	setScore(0);
	fillNext();
}

// **********************************************************************************************************************************
// Public Destructor
Model::~Model(){
	for (int i = 0 ; i < width ; i++){
		delete mapping[i];
	}
	delete * mapping;
}

// **********************************************************************************************************************************
// Getters		
int Model::getWidth() const { return width; }
int Model::getHeight() const { return height; }
double Model::getScore() const { return score; }
Item Model::getMapping(int i,int j) const { return mapping[i][j]; }
std::list<Block> * Model::getNext() { return &next; }
std::list<Block> * Model::getFalling() { return &falling; }

// **********************************************************************************************************************************		
// Setters
void Model::setWidth(int w) { width = w; }
void Model::setHeight(int h) { height = h; }
void Model::setScore(double s) {score = s; } 
void Model::setMapping(int i,int j,Item c) { mapping[i][j] = c; }

// **********************************************************************************************************************************		
// 
Block Model::makeRandomBlock(){
	Block b;
	for (int i = 0 ; i < 4 ; i++) b.data[i] = (Item)((rand() % 2)+1);
	return b;
}

void Model::fillNext(){
	for (int i = 0 ; i < NEXT ; i++){
		Block b = makeRandomBlock();
		b.x = 5;
		b.y = (i * 40); 
		next.push_back(b);
	}
}

void Model::popNextItem(){
	Block out = next.front();
	next.pop_front();
	next.push_back(makeRandomBlock());
	pushFallingItem(out);
}

void Model::pushFallingItem(Block b){
	// Need to get current music intensity so as to get speed.
	
}

void Model::connect(Block b){
}

void Model::updateMapping(){
}
